package com.zhuxiaomei.service.impl;

import com.zhuxiaomei.constant.JwtClaimsConstant;
import com.zhuxiaomei.context.BaseContext;
import com.zhuxiaomei.dto.user.*;
import com.zhuxiaomei.entity.msg.CoupleBindMessage;
import com.zhuxiaomei.entity.msg.WageConversionMessage;
import com.zhuxiaomei.entity.user.Couple;
import com.zhuxiaomei.entity.invitationCode.InvitationCode;
import com.zhuxiaomei.entity.user.User;
import com.zhuxiaomei.mapper.*;
import com.zhuxiaomei.properties.JwtProperties;
import com.zhuxiaomei.result.ReturnCodeEnum;
import com.zhuxiaomei.service.UserService;
import com.zhuxiaomei.utils.AESCryptoUtil;
import com.zhuxiaomei.utils.JwtUtil;
import com.zhuxiaomei.utils.MinioUtils;
import com.zhuxiaomei.vo.user.CoupleInfoVO;
import com.zhuxiaomei.vo.user.MineVO;
import com.zhuxiaomei.vo.user.UserInfoVO;
import com.zhuxiaomei.vo.user.UserLoginVO;
import jakarta.annotation.Resource;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;

/**
 * @author hxm
 * @date 2024/12/8 13:20
 * @description
 */
@Service
public class UserServiceImpl implements UserService {



    @Resource
    private JwtProperties jwtProperties;

    @Resource
    private MinioUtils minioUtils;

    @Resource
    private UserMapper userMapper;

    @Resource
    private CoupleMapper coupleMapper;

    @Resource
    private CoupleBindMessageMapper coupleBindMessageMapper;

    @Resource
    private InvitationCodeMapper invitationCodeMapper;

    @Resource
    private WageConversionMessageMapper wageConversionMessageMapper;



    @Override
    public UserLoginVO login(UserLoginDTO userLoginDTO) {
        User user = userMapper.getUserByAccount(userLoginDTO.getAccount());
        String passwdHex = DigestUtils.sha256Hex(AESCryptoUtil.decrypt(userLoginDTO.getPasswd()));
        Boolean isLogin = false;
        if (user != null) {
            isLogin = passwdHex.equals(user.getPasswd());
        }
        UserLoginVO userLoginVO = null;
        if (isLogin){
            HashMap claims = new HashMap();
            claims.put(JwtClaimsConstant.USER_ID, user.getId());
            String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);
            userLoginVO = UserLoginVO.builder().token(token).id(user.getId()).build();

        }
        return userLoginVO;
    }

    @Override
    public ReturnCodeEnum register(UserRegisterDTO userRegisterDTO) {
        //1.根据invitation查看邀请码是否有效
        InvitationCode invitationCode = invitationCodeMapper.isValid(userRegisterDTO.getInvitationCode());
        if (invitationCode == null){
            return ReturnCodeEnum.INVALID_INVITATION_CODE;
        }
        //2.根据account看看account是否已经存在
        User userByAccount = userMapper.getUserByAccount(userRegisterDTO.getAccount());
        if (userByAccount != null){
            return ReturnCodeEnum.ACCOUNT_ALREADY_EXISTS;
        }
        //3.account不存在，解密后加密，注册
        String passwdHex = DigestUtils.sha256Hex(AESCryptoUtil.decrypt(userRegisterDTO.getPasswd()));
        User registerUser = User.builder().account(userRegisterDTO.getAccount())
                .passwd(passwdHex)
                .userName("默认用户")
                .birthday(LocalDate.of(2000, 1, 1))
                .sex((byte) 1)
                .avatar("default.jpg")
                .balance(BigDecimal.valueOf(0)).build();
        Integer row = userMapper.registerUser(registerUser);
        if (row == 0) {
            return ReturnCodeEnum.USER_REGISTRATION_FAILURE;
        }
        invitationCode.setRemainingCount(invitationCode.getRemainingCount() - 1);
        invitationCodeMapper.updateByPrimaryKeySelective(invitationCode);
        return ReturnCodeEnum.RC200;
    }

    @Override
    public UserInfoVO getUserInfo(Long userId) {
        UserInfoVO userInfoVO = new UserInfoVO();
        User user = userMapper.selectByPrimaryKey(userId);
        String fileUrl = minioUtils.getFileUrl(user.getAvatar());
        user.setAvatar(fileUrl);
        BeanUtils.copyProperties(user, userInfoVO);
        return userInfoVO;
    }

    @Override
    public Integer updateUserInfo(UserInfoVO userInfoVO) {
        User user = new User();
        BeanUtils.copyProperties(userInfoVO, user);
        user.setId(BaseContext.getCurrentId());
        int res = userMapper.updateByPrimaryKeySelective(user);
        return res;
    }

    @Override
    public String updateUserPasswd(UserEditPasswdDTO userEditPasswdDTO) {
        Long currentId = BaseContext.getCurrentId();
        User currentUser = new User();
        currentUser.setId(currentId);
        User user = userMapper.selectByPrimaryKey(currentUser);
        if (user.getPasswd().equals(DigestUtils.sha256Hex(AESCryptoUtil.decrypt(userEditPasswdDTO.getOldPasswd())))) {
            user.setPasswd(DigestUtils.sha256Hex(AESCryptoUtil.decrypt(userEditPasswdDTO.getNewPasswd())));
            int row = userMapper.updateByPrimaryKeySelective(user);
            if (row > 0) {
                return ReturnCodeEnum.RC200.getCode();
            }
            return ReturnCodeEnum.RC999.getCode();
        }
        return ReturnCodeEnum.OLD_PASSWORD_ERROR.getCode();
    }

    @Override
    public MineVO getMineInfo() {
        Long currentId = BaseContext.getCurrentId();
        //根据当前id查询user
        User currentUser = userMapper.selectByPrimaryKey(currentId);
        //根据当前id查询couple
        Couple couple = new Couple();
        //男性
        Byte man = 1;
        if (man.equals(currentUser.getSex())) {
            couple.setManId(currentId);
        }else {
            couple.setWomanId(currentId);
        }
        Couple currentCouple = coupleMapper.selectOne(couple);
        //封装MineVO
        MineVO mineVO = new MineVO();
        mineVO.setCurrentSex(currentUser.getSex());
        //设置当前用户头像
        String currentUserAvatar = minioUtils.getFileUrl(currentUser.getAvatar());
        mineVO.setCurrentUserAvatar(currentUserAvatar);
        if (currentCouple == null) {
            return mineVO;
        }
        //设置当前伴侣头像
        User fere = userMapper.selectByPrimaryKey(currentCouple.getWomanId());
        String fereAvatar = minioUtils.getFileUrl(fere.getAvatar());
        mineVO.setCurrentFereAvatar(fereAvatar);
        //设置当前背景
        String backgroundPic = minioUtils.getFileUrl(currentCouple.getBackgroundPic());
        mineVO.setBackgroundPic(backgroundPic);
        //设置其他
        BeanUtils.copyProperties(currentCouple, mineVO);

        return mineVO;
    }

    @Override
    public CoupleInfoVO getCoupleInfo() {
        Long currentId = BaseContext.getCurrentId();
        Couple coupleInfo = coupleMapper.selectByManOrWomanID(currentId);
        if (coupleInfo == null) {
            return null;
        }
        CoupleInfoVO coupleInfoVO = new CoupleInfoVO();
        BeanUtils.copyProperties(coupleInfo, coupleInfoVO);
        String fileUrl = minioUtils.getFileUrl(coupleInfo.getBackgroundPic());
        coupleInfoVO.setBackgroundPic(fileUrl);
        return coupleInfoVO;
    }

    @Override
    public UserInfoVO getUserInfoByAccount(String account) {
        User userByAccount = userMapper.getUserByAccount(account);
        if (userByAccount == null) {
            return null;
        }
        Couple couple = coupleMapper.selectByManOrWomanID(userByAccount.getId());
        UserInfoVO userInfoVO = new UserInfoVO();
        if (couple == null) {
            userInfoVO.setHasFere("0");
        }else {
            userInfoVO.setHasFere("1");
        }
        BeanUtils.copyProperties(userByAccount, userInfoVO);
        String fileUrl = minioUtils.getFileUrl(userByAccount.getAvatar());
        userInfoVO.setAvatar(fileUrl);
        return userInfoVO;
    }

    @Override
    public Boolean bindCouple(CoupleBindDTO coupleBindDTO) {
        //coupleBindDTO.status == 3拒绝接受，返回false
        CoupleBindMessage msg = CoupleBindMessage.builder().fromAccount(coupleBindDTO.getFromUser()).toAccount(coupleBindDTO.getToUser()).status(coupleBindDTO.getStatus()).build();
        coupleBindMessageMapper.updateByFromUserAndToUser(msg);
        if ("3".equals(coupleBindDTO.getStatus())){
            return false;
        }
        // coupleBindDTO.status == 2，接受，然后新增couple，返回true
        Couple couple = new Couple();
        User fromUser = userMapper.getUserByAccount(coupleBindDTO.getFromUser());
        Long toUserId = userMapper.getUserByAccount(coupleBindDTO.getToUser()).getId();
        Byte man = 1;
        if (fromUser.getSex().equals(man)){
            couple.setManId(fromUser.getId());
            couple.setWomanId(toUserId);
        }else {
            couple.setManId(toUserId);
            couple.setWomanId(fromUser.getId());
        }
        LocalDate defaultTime = LocalDate.of(2000, 1, 1);
        couple.setBackgroundPic("default.jpg");
        couple.setCouplesName("默认组合名");
        couple.setFirstMeetDay(defaultTime);
        couple.setConfirmLoveDay(defaultTime);
        couple.setWeddingDay(defaultTime);
        coupleMapper.insertCouple(couple);

        return true;
    }


    @Override
    public Integer updateCoupleInfo(CoupleInfoVO coupleInfoVO) {
        Long currentId = BaseContext.getCurrentId();
        Couple couple = new Couple();
        BeanUtils.copyProperties(coupleInfoVO, couple);
        Integer row = coupleMapper.updateCoupleByManOrWomanId(couple, currentId);
        return row;
    }

    @Override
    public UserBalanceDTO getUserBalance() {
        User user = userMapper.selectByPrimaryKey(BaseContext.getCurrentId());
        UserBalanceDTO userBalanceDTO = UserBalanceDTO.builder().balance(user.getBalance().toString()).build();
        return userBalanceDTO;
    }

    @Override
    public void newWageConversion(WageConversionMessage wageConversionMessage) {
        Couple couple = coupleMapper.selectByManOrWomanID(wageConversionMessage.getRequestUser());
        if (couple.getManId().equals(wageConversionMessage.getRequestUser())){
            wageConversionMessage.setResponseUser(couple.getWomanId());
        }else {
            wageConversionMessage.setResponseUser(couple.getManId());
        }
        wageConversionMessage.setStatus(1);
        wageConversionMessageMapper.insert(wageConversionMessage);
    }

    @Override
    public List<WageConversionMessage> wageConversionMessage() {
        List<WageConversionMessage> conversionMessageList = wageConversionMessageMapper.selectByRequestUserOrResponserUser(BaseContext.getCurrentId());
        return conversionMessageList;
    }

    @Override
    public void editWageConversionMessage(WageConversionMessage wageConversionMessage) {
        WageConversionMessage message = wageConversionMessageMapper.selectByPrimaryKey(wageConversionMessage.getId());
        if (wageConversionMessage.getStatus().equals(3)){
            wageConversionMessageMapper.updateByPrimaryKeySelective(wageConversionMessage);
        } else if (wageConversionMessage.getStatus().equals(2)) {
            User requestUser = userMapper.selectByPrimaryKey(message.getRequestUser());
            requestUser.setBalance(requestUser.getBalance().add(message.getCoin()));
            userMapper.updateByPrimaryKeySelective(requestUser);
        }
    }
}
